package cn.melonlib.cores.aop.comp.crud;

import cn.hutool.core.util.ArrayUtil;
import cn.melonlib.cores.aop.anno.crud.CrudAround;
import cn.melonlib.cores.aop.anno.crud.CrudPoint;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
public class CrudInterceptor extends ApplicationObjectSupport implements MethodInterceptor {
    @Nullable
    @Override
    public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
        Object[] params = invocation.getArguments();
        CrudAround crudAround = AnnotationUtils.findAnnotation(AopUtils.getTargetClass(invocation.getThis()), CrudAround.class);
        if (crudAround != null) {
            List<Object> aopBeans = Stream.concat(Arrays.stream(ArrayUtil.addAll(crudAround.beforeSearchs(), crudAround.postSearchs(),
                            crudAround.beforeSaves(), crudAround.postSaves(),
                            crudAround.beforeRemoves(), crudAround.postRemoves())).filter(p -> {
                        Pattern pattern = Pattern.compile(p.scan());
                        return pattern.matcher(invocation.getMethod().getName()).matches();
                    }), Stream.of(AnnotationUtils.findAnnotation(invocation.getMethod(), CrudPoint.class)))
                    .flatMap(p-> Arrays.stream(p.value()))
                    .map(name -> {
                        try {
                            return getApplicationContext().getBean(name);
                        }catch(Exception e){
                            logger.error("没有找到注入的AOP对象："+name,e);
                            return null;
                        }
                    }).filter(Objects::nonNull).collect(Collectors.toList());


//            if(ArrayUtils.isNotEmpty(crudAround.beforeSearchs())){
//                Arrays.stream(crudAround.beforeSearchs()).forEach(item->{
//                    BeforeSearch beforeSearch=getApplicationContext().getBean(item, BeforeSearch.class);
//                    Arrays.stream(ResolvableType.forClass(beforeSearch.getClass()).getInterfaces()).filter(inf->Objects.equals(inf.toClass(),BeforeSearch.class)).forEach(inf->{
//                        Class<?> cls=inf.getGeneric(0).toClass();
//                        Arrays.stream(params).filter(param-> Objects.equals(param,cls)).forEach(param->{
//                            beforeSearch.before(param);
//                        });
//                    });
//                });
//            }
            Object entity = invocation.proceed();

        }


        return invocation.proceed();
    }
}
